/**
 * @file circuit_node.c
 * @author Linquan  
 * @brief   回路节点管理，
 *          提供回路通用节点结构
 *          对回路节点进行操作
 * 
 * @version 1.0
 * @date 2024-08-17
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "circuit_node.h"
#include "circuit_node_collection.h"




/**
 * @brief Get the node config data object
 *  传入一个接收的指针，这个接收的指针需要有一块空间，用于保存接受到的数据。不能只创建一个指针就传进来。
 * @param node_ptr 
 * @param cfg_data 
 */
void get_node_config_data(circuit_node_t *node_ptr, config_data_store_t *cfg_data)
{
    if (node_ptr == NULL || cfg_data == NULL)
    {
        error_log("node ptr or data is null");
        cfg_data->config_data_store_ptr = NULL;
        return;
    }
    
   cfg_data->node_type = node_ptr->node_type;
   cfg_data->config_data_store_ptr = (circuit_node_config_t*)node_ptr->node_config_data;
}


/**
 * @brief Get the node real time data object
 * 
 * @param node_ptr 
 * @param cfg_data 
 */
void get_node_real_time_data(circuit_node_t *node_ptr, rt_data_store_t *rt_data)
{
    if (node_ptr == NULL || rt_data == NULL)
    {
        error_log("node ptr or data is null");
        rt_data->rt_data_store_ptr = NULL;
        return;
    }
    
   rt_data->node_type = node_ptr->node_type;
   rt_data->rt_data_store_ptr = (circuit_node_rt_data_t*)node_ptr->node_config_data;
}




/**
 * @brief Get the node by node type object
 * 
 * @param muti_addr 
 * @attention 重要： 需要对返回的值 muti_addr->node_ptr 做空指针校验！！！
 */
void get_node_by_muti_addr(muti_addr_t *muti_addr)
{
    uint32_t cycle_timeout = 0;             /** 剥离地址最大次数 */
    uint8_t  fail_flag = 0;
    circuit_node_t           *node_ptr;     /** 节点指针 */
    node_operate_irf_t       *op_ptr;       /** 模块的操作函数指针 */
    circuit_node_type_t      node_type;     /** 节点类型 */
   

    /** 1、当多级地址级数为0，将传入数据原路返回  */
    if(muti_addr->addr_num == 0 || muti_addr->node_ptr == NULL)
    {
        error_log("the addr number is zero! or the node ptr is null!");
        {
            fail_flag = 1;
            goto find_node_ptr_fail;
        }
    }

    /** 2、调用 各个模块的操作函数， 一层一层把 地址级数剥离，每次剥离，地址级数减少，地址指针向后偏移
     * 当级数变为0，最后muti_addr->node_ptr 节点指针就是最后需要的
     */
    while (muti_addr->addr_num && cycle_timeout < 0XFF)
    {
        cycle_timeout++;

        /** 2.1、更新 地址指针位置和 节点类型 */
        node_ptr = muti_addr->node_ptr;
        node_type = node_ptr->node_type;

        /** 2.2、根据节点类型获得操作指针 */
        op_ptr = get_op_irf_by_circuit_node_type( node_type);
    
        /** 2.3、 调用操作函数，传入找节点命令 ,当IO操作函数操作未成功，直接返回NULL，本次查找失败 */
        if(op_ptr)
        {   
            int32_t  result = op_ptr->irfIoCtrl(node_ptr, OP_CODE_FIND_NODE, muti_addr);  

            if(result != OP_SUCCESS)
            {
                error_log("node type:[%d] operate function is not sucess. the result is : %d ",node_type, result);
                {
                    fail_flag = 1;
                    goto find_node_ptr_fail;
                }
            }
        }
        else
        {
            error_log("node type: %d's op function is not support!",node_type);
            {
                fail_flag = 1;
                goto find_node_ptr_fail;
            }
        }   
     }

    /** 3、当上述循环超时，本次查找失败，节点返回NULL */
    if(cycle_timeout >= 0XFF)
    {
        error_log("cycle is time out ,not find node ");
        {
            fail_flag = 1;
            goto find_node_ptr_fail;
        }
    }

    find_node_ptr_fail:
    if(fail_flag)
    {
        muti_addr->node_ptr = NULL;
    }  
}












